#include "Headers.h"

void CurlGlobalInit ()
{

    CURLcode return_code = curl_global_init(CURL_GLOBAL_ALL);
    CURLoops(return_code , "init libcurl  ");

}

Handle  GetEasyHandle ()
{

    Handle easy_handle = curl_easy_init();
    if (easy_handle == NULL)
    {
        curl_global_cleanup();
        oops("get a easy handle  ");
    }
    return easy_handle;

}

void InitMemoryStruct (MemoryStruct * tmp_mem)
{
    tmp_mem->memory = malloc(1);
    tmp_mem->size = 0;
}

FileStruct GetFileStruct (const char * filename)
{
    FileStruct tmp;
    tmp.fp = fopen(filename , "w+");
    if (tmp.fp == NULL)
        oops("fopen file");
    tmp.size = 0;
    return tmp;
}

void SetHttpGet (Handle easy_handle , const char *url)
{

    if (easy_handle)
    {
        CURLcode set_url = curl_easy_setopt(easy_handle,CURLOPT_URL,url);
        CURLoops(set_url , "CURLOPT_URL");

        CURLcode set_get = curl_easy_setopt(easy_handle,CURLOPT_HTTPGET,1);
        CURLoops(set_get , "CURLOPT_HTTPGET");
    }

}

void SetHttpPost(Handle easy_handle , const char *url , const char *postdata)
{

    if (easy_handle)
    {
        CURLcode set_url = curl_easy_setopt(easy_handle,CURLOPT_URL,url);
        CURLoops(set_url,"CURLOPT_URL");

        CURLcode set_post_field = curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, postdata);
        CURLoops(set_post_field,"CURLOPT_POSTFIELDS");

        CURLcode set_post = curl_easy_setopt(easy_handle, CURLOPT_POST, 1);
        CURLoops(set_post,"CURLOPT_POST");
    }

}

void SetHttpRedirect (Handle easy_handle , long max_redir)
{

    if (easy_handle)
    {
        if (max_redir)
        {

            CURLcode set_max_redir = curl_easy_setopt(easy_handle , CURLOPT_MAXREDIRS , max_redir);
            CURLoops(set_max_redir , "CURLOPT_MAXREDIRS");

            CURLcode set_http_redir = curl_easy_setopt(easy_handle , CURLOPT_FOLLOWLOCATION , 1L);
            CURLoops(set_http_redir , "CURLOPT_FOLLOWLOCATION");

        }
        else
        {

            CURLcode set_http_redir = curl_easy_setopt(easy_handle , CURLOPT_FOLLOWLOCATION , 0L);
            CURLoops(set_http_redir , "CURLOPT_FOLLOWLOCATION");

        }

    }

}

void SendRequest (Handle  easy_handle)
{

    CURLcode curl_stat= curl_easy_perform(easy_handle);

    if (curl_stat != CURLE_OK)
    {
        curl_easy_cleanup(easy_handle);
        fprintf(stderr, "%s : %s\n",  "Send request" , curl_easy_strerror(curl_stat));
        exit(1);
    }

}

int GetHttpResponseCode (Handle  easy_handle)
{

    int response_code;
    CURLcode  res = curl_easy_getinfo(easy_handle , CURLINFO_RESPONSE_CODE , &response_code);
    CURLoops(res , "CURLINFO_RESPONSE_CODE");

    return response_code;
}

void ImportHttpCookies (Handle  easy_handle , const char * cookies , int Isfile)
{
    if (Isfile)
        curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE , cookies);
    else
        curl_easy_setopt(easy_handle , CURLOPT_COOKIE , cookies);
}


/*
Handle ImportHttpCookiesFiles(Handle  easy_handlle , char * filepath)
{

}
*/

void SetHttpAuth (Handle  easy_handle , char *url , char * username , char * password)
{

    CURLcode set_url = curl_easy_setopt(easy_handle , CURLOPT_URL , url);
    CURLoops(set_url , "set CURLOPT_URL");

    CURLcode set_auth = curl_easy_setopt(easy_handle , CURLOPT_HTTPAUTH , (long)CURLAUTH_ANY );
    CURLoops(set_auth , "set CURLOPT_HTTPAUTH");

    CURLcode set_username = curl_easy_setopt(easy_handle , CURLOPT_USERNAME , username);
    CURLoops(set_username , "set CURLOPT_USERNAME");

    CURLcode set_password = curl_easy_setopt(easy_handle , CURLOPT_PASSWORD , password);
    CURLoops(set_password , "set CURLOPT_PASSWORD");

}


void SetHttpProxy (Handle  easy_handle , const char * host , long port , const char * username , const char * password)
{

    CURLcode set_proxy = curl_easy_setopt(easy_handle , CURLOPT_PROXY , host);
    CURLoops(set_proxy , "set CURLOPT_PROXY");

    CURLcode set_proxy_type = curl_easy_setopt(easy_handle , CURLOPT_PROXYTYPE , CURLPROXY_HTTP);
    CURLoops(set_proxy_type , "set CURLOPT_PROXYTYPE");

    CURLcode set_proxy_port = curl_easy_setopt(easy_handle , CURLOPT_PROXYPORT , port);
    CURLoops(set_proxy_port , "set CURLOPT_PROXYPORT");

    if (username == NULL)
    {
        return ;
    }

    CURLcode set_proxy_auth = curl_easy_setopt(easy_handle , CURLOPT_PROXYAUTH , CURLAUTH_ANY);
    CURLoops(set_proxy_auth , "set CURLOPT_PROXYAUTH");

    int len_user = strlen(username);
    int len_pass = strlen(password);
    char * userpwd = (char *)malloc(len_user + len_pass + 4);
    strcat(userpwd,username);
    strcat(userpwd,":");
    strcat(userpwd,password);

    CURLcode set_proxy_userpwd = curl_easy_setopt(easy_handle , CURLOPT_PROXYUSERPWD , userpwd);
    CURLoops(set_proxy_userpwd , "set CURLOPT_PROXYUSERPWD");

    free(userpwd);
    userpwd = NULL;

}

void EditHttpHeaders (Handle  easy_handle , const char *s , HttpHeader slist)
{

    slist = curl_slist_append(slist , s);

    if (slist == NULL)
    {
        oops ("EditHttpHeaders  ");
    }

    curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, slist);

}

void SetHttpHead(Handle easy_handle , const char *url , int File_Mem , void * tmp)
{

    if (easy_handle)
    {
        CURLcode set_url = curl_easy_setopt(easy_handle,CURLOPT_URL,url);
        CURLoops(set_url , "CURLOPT_URL");

        CURLcode set_head = curl_easy_setopt(easy_handle, CURLOPT_NOBODY, 1L);
        CURLoops(set_head , "CURLOPT_NOBODY");

        if (File_Mem) // Mem
        {
            CURLcode head2mem = curl_easy_setopt(easy_handle , CURLOPT_HEADERFUNCTION , WriteMemoryCallback);
            CURLoops(head2mem , "http head WriteMemCallback");
        }
        else
        {
            CURLcode head2mem = curl_easy_setopt(easy_handle , CURLOPT_HEADERFUNCTION , writeFileCallback);
            CURLoops(head2mem , "http head WriteFileCallback");
        }

        CURLcode set_head_data = curl_easy_setopt(easy_handle, CURLOPT_HEADERDATA , (void *)tmp);
        CURLoops(set_head_data , "http head CURLOPT_WRITEDATA");

    }

}

void SaveTrafficData (Handle easy_handle , int Up_Down , int File_mem , void * tmp_memory)
{

    if (easy_handle)
    {

        if (Up_Down) // download
        {

            if (File_mem)
            {
                CURLcode download2mem =  curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
                CURLoops(download2mem , "CURLOPT_WRITEFUNCTION");
            }
            else
            {
                CURLcode download2mem =  curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, writeFileCallback);
                CURLoops(download2mem , "CURLOPT_WRITEFUNCTION");
            }

            CURLcode set_write_data = curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, (void *)tmp_memory);
            CURLoops(set_write_data , "CURLOPT_WRITEDATA");

        }
        /* else  // upload
         {

             CURLcode download2mem =  curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, WriteMemoryCallback);

             curl_easy_setopt(easy_handle, CURLOPT_READDATA, (void *)tmp_memory);

         }
        */

    }

}

void SeparateString (void * input , const char * head , const char * tail , int output_type , void * output)
{

    MemoryStruct * mem = (MemoryStruct *)input;
    FileStruct * stream = (FileStruct *)output;

    char *p_init = mem->memory;
    char *p_head = mem->memory;
    char *p_tail = mem->memory;

    ssize_t len_init = strlen(p_init);
    ssize_t len_head , len_tail , i , num_character = 0;
    ssize_t len_tail_str = strlen(tail);

    while ( p_head = strstr(p_init , head) )
    {
        len_head = strlen(p_head);
        p_tail = strstr(p_head , tail);
        len_tail = strlen(p_tail);

        for (i=0 ; i < len_head - len_tail ; i++)
        {
            fputc(p_head[i] , stream->fp);
            num_character++;
        }
        fputc( '\r' , stream->fp);
        num_character++;

        p_tail += len_tail_str;
        p_head = p_init = p_tail;
    }
    stream->size = num_character;

}

int main(int ac , char *av[])
{

    CurlGlobalInit();
    char *url = "http://www.baidu.com/s?wd=123&ie=utf-8";
    Handle  handle = GetEasyHandle();
    CURLcode set_url = curl_easy_setopt(handle,CURLOPT_URL,url);
    //SetHttpProxy(handle , "127.0.0.1" , 8080 , NULL , NULL);

    //SetHttpGet(handle , url);
    //SetHttpHead(handle , url , 0 , &test);

    MemoryStruct tmp;
    InitMemoryStruct(&tmp);

    SaveTrafficData(handle , 1 , 1 , &tmp);
    SendRequest(handle);
    printf("%lu\n",tmp.size);

    FileStruct fp = GetFileStruct("/home/flygend/123");
    SeparateString( &tmp , "http://www.baidu.com/link?url=" , "\"" , 1 , &fp);

    /*
    int i;
    for (i=0; i<tmp.size; i++)
    {
        printf("%c",tmp.memory[i]);
    }
    */
    printf("%d\n",GetHttpResponseCode(handle));

    return 0;
}

/*
    FileStruct test = GetFileStruct("/home/flygend/321");
    SaveTrafficData(handle , 1 , 0 , &test);
    printf("%lu\n",test.size);
*/
